<!--
 * @Author: cjx
 * @Date: 2023-04-18 17:43:40
 * @LastEditTime: 2023-04-19 13:47:51
 * @Description: 日期选择器
 * @param {String} prop 需要赋值的字段名称
 *
 * 组合为范围日期选择时，才使用以下属性
 * datePos、dateJudge 同时存在时开启禁用效果
 * @param {String} datePos 日期位置 start|end
 * @param {String} dateJudge 开始或者结束日期
-->

<template>
  <DatePicker
    :model-value="computedVal"
    :type="type"
    :placement="placement"
    :size="size"
    :placeholder="placeholder"
    :split-panels="splitPanels"
    :options="options"
    v-bind="$attrs"
    @on-change="changeHandle"
  />
</template>

<script lang="ts" setup>
import { computed } from '@vue/reactivity'

const props = defineProps({
  modelValue: {
    type: [String, Array<string>],
    default: () => []
  },
  type: {
    type: String,
    default: 'daterange'
  },
  prop: {
    type: String,
    default: ''
  },
  size: {
    type: String,
    default: 'default'
  },
  placement: {
    type: String,
    default: 'bottom-start'
  },
  placeholder: {
    type: String,
    default: '请选择日期'
  },
  splitPanels: {
    type: Boolean,
    default: true
  },
  datePos: {
    type: String,
    default: ''
  },
  dateJudge: {
    type: String,
    default: ''
  }
})

const emits = defineEmits(['update:modelValue', 'on-change'])

const computedVal = computed({
  get: () => {
    const valPrototypeType = Object.prototype.toString.call(props.modelValue) // 数据类型判断
    if (valPrototypeType === '[object Array]') {
      return props.modelValue.length === 0 ? (props.type === 'date' ? '' : []) : props.modelValue
    } else if (valPrototypeType === '[object Date]') {
      // 日期格式为标准格式时，主动转换位常用格式
      const newVal = dateFormat(props.modelValue, 'yyyy-MM-dd')
      emits('update:modelValue', newVal)
      return newVal
    } else {
      return props.modelValue
    }
  },
  set: (val) => {
    emits('update:modelValue', val)
  }
})

// 选择器额外配置
const options = computed(() => {
  const dateJudge = new Date(props.dateJudge).valueOf() || 0
  return {
    disabledDate(date: any) {
      let disabledDate = false
      const curDateNum = date && date.valueOf()
      if (props.datePos && dateJudge !== 0) {
        if (props.datePos === 'start') {
          // 禁用结束日期后的所有日期
          disabledDate = curDateNum > dateJudge
        } else {
          // 禁用开始日期前的所有日期（包含当前选中的开始日期）
          disabledDate = curDateNum < dateJudge - 60 * 60 * 24 * 1000
        }
      }
      return disabledDate
    }
  }
})

// 变更回调
const changeHandle = (date: any) => {
  emits('update:modelValue', date)

  // 统一返回 选择的日期和需要赋值的
  // 通过调用外部on-change方法赋值
  const prop = props.prop.split(',')
  emits('on-change', { date, prop })
}

const dateFormat = (date: any, fmt: string) => {
  const o: any = {
    'M+': date.getMonth() + 1, //月份
    'd+': date.getDate(), //日
    'h+': date.getHours(), //小时
    'm+': date.getMinutes(), //分
    's+': date.getSeconds(), //秒
    'q+': Math.floor((date.getMonth() + 3) / 3), //季度
    S: date.getMilliseconds() //毫秒
  }
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  for (let k in o)
    if (new RegExp('(' + k + ')').test(fmt))
      fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
  return fmt
}
</script>
